#ifndef __LIBS_TYPES_H__
#define __LIBS_TYPES_H__

#ifndef NULL
#define NULL ((void *)0)
#endif

/* Represents true-or-false values */
typedef int bool;

/* Explicitly-sized versions of integer types */
typedef char int8_t;
typedef unsigned char uint8_t;
typedef short int16_t;
typedef unsigned short uint16_t;
typedef int int32_t;
typedef unsigned int uint32_t;
typedef long long int64_t;
typedef unsigned long long uint64_t;

/* size_t is used for memory object sizes */
typedef uint32_t size_t;

/* *
 * Pointers and addresses are 32 bits long.
 * We use pointer types to represent addresses,
 * uintptr_t to represent the numerical values of addresses.
 * */
typedef int32_t intptr_t;
typedef uint32_t uintptr_t;

/* page numbers are 32 bits long */
typedef uint32_t ppn_t;

/* *
 * Rounding operations (efficient when n is a power of 2)
 * Round down to the nearest multiple of n
 * */
#define ROUNDDOWN(a, n) ({						\
	uint32_t __a = (uint32_t)(a);				\
	(typeof(a))(__a - __a % (n));				\
})

/* Round up to the nearest multiple of n */
#define ROUNDUP(a, n) ({						\
	uint32_t __n = (uint32_t)(n);				\
	(typeof(a))(ROUNDDOWN((uint32_t)(a) + __n - 1, __n));		\
})

/* Return the offset of 'member' relative to the beginning of a struct type */
#define offsetof(type, member)					\
	((size_t)(&((type *)0)->member))

/* *
 * to_struct - get the struct from a ptr
 * @ptr:	a struct pointer of member
 * @type:	the type of the struct this is embedded in
 * @member:	the name of the member within the struct
 * */
#define to_struct(ptr, type, member)			\
	((type *)((char *)(ptr) - offsetof(type, member)))

#endif /* !__LIBS_TYPES_H__ */

